﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Ink;
//using System.Windows.Forms;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using BioImg;
using GMap.NET;
using GMap.NET.MapProviders;
using GMap.NET.Projections;
//using GMap.NET.WindowsForms;
using GMap.NET.WindowsPresentation;
using GMapWpf.Custom;
using Microsoft.Win32;

namespace GMapWpf
{
    /// <summary>
    /// MainWindow.xaml 的交互逻辑
    /// </summary>
    /// <summary>
    /// MainWindow.xaml 的交互逻辑
    /// </summary>
    public partial class MainWindow : Window
    {
       
            public MainWindow()
        {
            InitializeComponent();
            //mapControl.CacheLocation = System.IO.Path.Combine(System.Windows.Forms.Application.StartupPath, "Gmap");//指定地图缓存存放路径
            mapControl.Manager.Mode = GMap.NET.AccessMode.ServerOnly;// ServerOnly;// ServerAndCache;
            mapControl.MapProvider = BioImgProvider.Instance;

            //mapControl.Manager.Mode = AccessMode.CacheOnly;
            //mapControl.MapProvider = GMap.NET.MapProviders.GMapProviders.GoogleChinaMap; //google china 地图
            //mapControl.MinZoom = 2;  //最小缩放
            //mapControl.MaxZoom = 17; //最大缩放
            mapControl.Zoom = 6;     //当前缩放
            mapControl.ShowCenter = false; //不显示中心十字点
            mapControl.DragButton = MouseButton.Left; //左键拖拽地图
            //mapControl.Position = new PointLatLng(32.064, 118.704); //地图中心位置：南京
            PointLatLng lPoint = MercatorProjection.Instance.FromPixelToLatLng(0, 0, 6);
            mapControl.Position = lPoint;
            mapControl.MouseMove += MapControl_MouseMove;
            mapControl.MouseWheel += MapControl_MouseWheel; 
            viewModel = new ViewModel
            {
                MeaInfo = "测试······",
                InkStrokes = new StrokeCollection(),
            };
            DataContext = viewModel;
            CreatPathHepler.mapControl = mapControl;
            CreatPathHepler.gridRoot = gridRoot;
        }

        bool isVisibility = false;

        private void SetinkCanvasMeasure(bool _isVisibility)
        {
            isVisibility = _isVisibility;
            if (_isVisibility)
            {
                inkCanvasMeasure.Visibility = Visibility.Visible;
            }
            else
            {
                inkCanvasMeasure.Visibility = Visibility.Collapsed;
            }
            setIsChecked();
        }

        public AreaStruct.AreaDrawType m_drawType = AreaStruct.AreaDrawType.DT_NONE;
        #region MyRegion
        private void OpenFile_Click(object sender, RoutedEventArgs e)
        {
            m_drawType = AreaStruct.AreaDrawType.DT_NONE;
            SetinkCanvasMeasure(!isVisibility);
        }
        private void setIsChecked()
        {
            //btnMove.IsChecked = false;
            btnPolygon.IsChecked = false;
            btnSquare.IsChecked = false;
            btnEllipse.IsChecked = false;

            switch (m_drawType)
            {
                case AreaStruct.AreaDrawType.DT_POLYGON:
                    btnPolygon.IsChecked = true;
                    break;
                case AreaStruct.AreaDrawType.DT_RECTANGLE:
                    btnSquare.IsChecked = true;
                    break;
                case AreaStruct.AreaDrawType.DT_ELLIPSE:
                    btnEllipse.IsChecked = true;
                    break;
            }

        }
        //btnPolygon.IsChecked
        private void DrawPolygon_Click(object sender, RoutedEventArgs e)
        {
            m_drawType = AreaStruct.AreaDrawType.DT_POLYGON;
            SetinkCanvasMeasure(true);
        }

        private void DrawSquare_Click(object sender, RoutedEventArgs e)
        {
            m_drawType = AreaStruct.AreaDrawType.DT_RECTANGLE;
            SetinkCanvasMeasure(true);
        }

        private void DrawEllipse_Click(object sender, RoutedEventArgs e)
        {
            m_drawType = AreaStruct.AreaDrawType.DT_ELLIPSE;
            SetinkCanvasMeasure(true);
        }
        #endregion


        private List<Point> GeneratePolygonGeometry(System.Windows.Point ed)
        { 
            List<System.Windows.Point> pointList = new List<System.Windows.Point>();
            pointList = iniPList.ToArray().ToList();
            pointList.Add(ed); 
            return pointList;
        }

        #region MyRegion

        private ViewModel viewModel;
        private System.Windows.Point iniP;
        private List<System.Windows.Point> GenerateEclipseGeometry(System.Windows.Point st, System.Windows.Point ed)
        {
            double a = 0.5 * (ed.X - st.X);
            double b = 0.5 * (ed.Y - st.Y);
            List<System.Windows.Point> pointList = new List<System.Windows.Point>();
            for (double r = 0; r <= 2 * Math.PI; r = r + 0.01)
            {
                pointList.Add(new System.Windows.Point(0.5 * (st.X + ed.X) + a * Math.Cos(r), 0.5 * (st.Y + ed.Y) + b * Math.Sin(r)));
            }
            return pointList;
        }

        List<Point> iniPList = new List<Point>();
        private void InkCanvasMeasure_MouseDown(object sender, MouseButtonEventArgs e)
        {
            if (e.LeftButton == MouseButtonState.Pressed)
            {
                iniP = e.GetPosition(inkCanvasMeasure);

                iniPList.Add(iniP);
                Point clickPoint = iniP;// e.GetPosition(mapControl);
                //pointList.Add(new Point((int)clickPoint.X, (int)clickPoint.Y));
                if (m_drawType == AreaStruct.AreaDrawType.DT_POLYGON)
                {
                    if (iniPList.Count > 1)
                    {
                        Point beginPoint = iniPList[0];
                        double xDistance = beginPoint.X - clickPoint.X;
                        double yDistance = beginPoint.Y - clickPoint.Y;
                        double value = Math.Sqrt((double)(xDistance * xDistance + yDistance * yDistance));
                        if (value < 8.0)
                        {
                            PointLatLng point2 = mapControl.FromLocalToLatLng((int)beginPoint.X, (int)beginPoint.Y);
                            CreatPathHepler.pointLatList.Add(point2);
                            buildPolygonArea();
                            return;
                        }
                    }
                }
              
                PointLatLng point = mapControl.FromLocalToLatLng((int)clickPoint.X, (int)clickPoint.Y);
                CreatPathHepler.pointLatList.Add(point);
                if (m_drawType != AreaStruct.AreaDrawType.DT_POLYGON)
                {
                    if (CreatPathHepler.pointLatList.Count>= 2)
                    {
                        buildPolygonArea();
                    }
                }

            }
        }
        public int m_iMaxIndexNow=0;//备注的最大编号
        public string remark = "";
        public int category =0;//分类
   
        private void buildPolygonArea()
        {
            AreaStruct.AreaDefine area = new AreaStruct.AreaDefine();
            area.m_iIndex = m_iMaxIndexNow;
            area.m_Type = m_drawType;
            area.remark = remark;
            area.category = category;
            area.Zoom = mapControl.Zoom;
            area.m_ListPoint = CreatPathHepler.pointLatList.ToArray().ToList();
            CreatPathHepler.m_lstImgIndex.Add(area);
            SavePointLatList();
            CreatPathHepler.pointLatList.Clear();
            iniP= new Point(0, 0);
            iniPList.Clear();
            viewModel.InkStrokes.Clear();
            m_iMaxIndexNow++;
            UpdateSave();
            //area.ratioZNow = ratioZNow;
            //area.leftTopNowX = leftTopNowX;
            //area.leftTopNowY = leftTopNowY;
        }

        private void SavePointLatList()
        {
            PointLatLng point0 = CreatPathHepler.pointLatList[0];
            PointLatLng point1 = CreatPathHepler.pointLatList[1];
            PointLatLng point = point0;
            if (m_drawType == AreaStruct.AreaDrawType.DT_ELLIPSE)
            {
                double Lng = point0.Lng < point1.Lng ? point0.Lng : point1.Lng;
                point = new PointLatLng((point0.Lat + point1.Lat) / 2, Lng);
            }
            if (m_drawType == AreaStruct.AreaDrawType.DT_RECTANGLE)
            {
                double Lat = point0.Lat >point1.Lat ? point0.Lat : point1.Lat;
                double Lng = point0.Lng < point1.Lng ? point0.Lng : point1.Lng;
                point = new PointLatLng(Lat, Lng);
            }
            SaveMarkers(point);
        }
        private void SaveMarkers(PointLatLng point)
        {
            GMapMarker marker = new GMapMarker(point);
            TextBlock textBlock = new TextBlock();
            textBlock.Text = m_iMaxIndexNow.ToString();
            textBlock.FontSize = 12;
            marker.Shape = textBlock;
            marker.Offset = new Point(10, 10);
            if (m_drawType == AreaStruct.AreaDrawType.DT_ELLIPSE)
            {
                marker.Offset = new Point(0,0);
            }
            this.mapControl.Markers.Add(marker);
            SetinkCanvasMeasure(false);
            //this.mapControl.Markers.Clear();
        }


        private void InkCanvasMeasure_MouseMove(object sender, MouseEventArgs e)
        {
            if (true&& iniP!=new Point(0,0))//e.LeftButton != MouseButtonState.Pressed)
            {
                // Draw square
                if (m_drawType== AreaStruct.AreaDrawType.DT_RECTANGLE)
                {
                    System.Windows.Point endP = e.GetPosition(inkCanvasMeasure);
                    List<System.Windows.Point> pointList = new List<System.Windows.Point>
                      {
                        new System.Windows.Point(iniP.X, iniP.Y),
                        new System.Windows.Point(iniP.X, endP.Y),
                        new System.Windows.Point(endP.X, endP.Y),
                        new System.Windows.Point(endP.X, iniP.Y),
                        new System.Windows.Point(iniP.X, iniP.Y),
                      };
                    StylusPointCollection point = new StylusPointCollection(pointList);
                    Stroke stroke = new Stroke(point)
                    {
                        DrawingAttributes = inkCanvasMeasure.DefaultDrawingAttributes.Clone()
                    };
                    viewModel.InkStrokes.Clear();
                    viewModel.InkStrokes.Add(stroke);
                }
                // Draw Eclipse
                else if (m_drawType == AreaStruct.AreaDrawType.DT_ELLIPSE)
                {
                    System.Windows.Point endP = e.GetPosition(inkCanvasMeasure);
                    List<System.Windows.Point> pointList = GenerateEclipseGeometry(iniP, endP);
                    StylusPointCollection point = new StylusPointCollection(pointList);
                    Stroke stroke = new Stroke(point)
                    {
                        DrawingAttributes = inkCanvasMeasure.DefaultDrawingAttributes.Clone()
                    };
                    viewModel.InkStrokes.Clear();
                    viewModel.InkStrokes.Add(stroke);
                }
                // Draw Polygon
                else if (m_drawType == AreaStruct.AreaDrawType.DT_POLYGON)
                {
                    if (iniPList.Count == 0) return;
                    System.Windows.Point endP = e.GetPosition(inkCanvasMeasure);
                    List<System.Windows.Point> pointList = GeneratePolygonGeometry(endP);
                    StylusPointCollection point = new StylusPointCollection(pointList);
                    Stroke stroke = new Stroke(point)
                    {
                        DrawingAttributes = inkCanvasMeasure.DefaultDrawingAttributes.Clone()
                    };
                    viewModel.InkStrokes.Clear();
                    viewModel.InkStrokes.Add(stroke);
                }
             }

             
        }
        #endregion

        private void UpdateSave()
        {
            MapPath.Data = CreatPathHepler.CreatPath();
        }
        private void MapControl_MouseWheel(object sender, MouseWheelEventArgs e)
        {
            UpdateSave();
        }

        private void MapControl_MouseMove(object sender, MouseEventArgs e)
        {
            UpdateSave();
        }


        public class GmapPoint
        {
            public List<PointLatLng> pointLatList;


            public int type;
        }

        public class CreatPathHepler
        {
            public static List<AreaStruct.AreaDefine> m_lstImgIndex = new List<AreaStruct.AreaDefine>();
            public static MapControl mapControl;
            public static Grid gridRoot;

            //public static List<Point> pointList = new List<Point>();
            public static List<PointLatLng> pointLatList = new List<PointLatLng>();

            
            #region CreatPath
            public static Point ToCtrlPoint(PointLatLng gpsPoint)
            {
                //转换成GMap.NET控件坐标
                GPoint ptOfMapCtrl = mapControl.FromLatLngToLocal(gpsPoint);

                //GMap.NET控件坐标要转换成 控件相对于直接父面板的坐标
                Point ptToMapCtrl2 = new Point(ptOfMapCtrl.X, ptOfMapCtrl.Y);
                //转成屏幕坐标
                Point ptOfScreen = mapControl.PointToScreen(ptToMapCtrl2);
                //转换成相对于gridRoot的坐标
                Point ptOfParentPanel = gridRoot.PointFromScreen(ptOfScreen);//gridRoot

                return ptOfParentPanel;
            }

            public static GeometryGroup CreatPath()
            {
                //List<PointLatLng> _listPoints = pointLatList;
                //if (_listPoints == null || _listPoints?.Count <= 1)
                //{
                //    return null;
                //}

                //List<PointLatLng> listPt = _listPoints;
                //pointList.Clear();
                if(m_lstImgIndex.Count==0)
                {
                    return null;
                }
              
                List<PointLatLng> listPt = new List<PointLatLng>();
                GeometryGroup geometryGroup = new GeometryGroup();
                foreach (AreaStruct.AreaDefine areaDefine in m_lstImgIndex)
                {
                    if(areaDefine.m_Type== AreaStruct.AreaDrawType.DT_POLYGON)
                    {
                        listPt = areaDefine.m_ListPoint;
                        List<Point> pointList = new List<Point>();
                        #region PathGeometry
                        PathFigure pathFigure = new PathFigure();
                        pathFigure.StartPoint = ToCtrlPoint(listPt[0]); //起始点
                        pathFigure.IsClosed = true;
                        pointList.Add(pathFigure.StartPoint);
                        for (int i = 1; i < listPt.Count; i++)
                        {
                            Point point = ToCtrlPoint(listPt[i]);
                            pointList.Add(point);
                            //加入线段
                            LineSegment line = new LineSegment() { Point = point };
                            pathFigure.Segments.Add(line);
                        }
                        PathGeometry geometry = new PathGeometry();
                        geometry.Figures.Add(pathFigure);
                        geometryGroup.Children.Add(geometry);
                        #endregion
                    }
                    if(areaDefine.m_Type == AreaStruct.AreaDrawType.DT_RECTANGLE)
                    {
                        listPt = areaDefine.m_ListPoint;
                        List<Point> pointList = new List<Point>();
                        pointList.Add(ToCtrlPoint(listPt[0]));
                        pointList.Add(ToCtrlPoint(listPt[1]));
                        #region MyRegion
                        Rect rect = new Rect(pointList[0], pointList[1]);
                        RectangleGeometry rectangleGeometry = new RectangleGeometry(rect);
                        geometryGroup.Children.Add(rectangleGeometry);
                        #endregion

                    }
                    if (areaDefine.m_Type == AreaStruct.AreaDrawType.DT_ELLIPSE)
                    {
                        listPt = areaDefine.m_ListPoint;
                        List<Point> pointList = new List<Point>();
                        pointList.Add(ToCtrlPoint(listPt[0]));
                        pointList.Add(ToCtrlPoint(listPt[1]));
                        #region EllipseGeometry
                        EllipseGeometry ellipseGeometry = new EllipseGeometry();
                        ellipseGeometry.Center = new Point((pointList[0].X + pointList[1].X) / 2, (pointList[0].Y + pointList[1].Y) / 2);
                        ellipseGeometry.RadiusX = Math.Abs((pointList[0].X - pointList[1].X) / 2);
                        ellipseGeometry.RadiusY = Math.Abs((pointList[0].Y - pointList[1].Y) / 2);
                        #endregion
                        geometryGroup.Children.Add(ellipseGeometry);
                    }
                }
              

            
               


          
                
          
            
 

                //geometry.Figures.Add(ellipseGeometry);
                return geometryGroup;
            }

            #region CreateTextPath 用来显示文字的
            public static Geometry CreateTextPath(string word, Point point, int fontsize)
            {
                var pathgeometry = CreateTextPath(word, point,
                    new Typeface(new FontFamily("Arial"), FontStyles.Normal, FontWeights.Bold, FontStretches.Normal), (int)fontsize);
                return pathgeometry;
            }

            /// <summary>
            /// 创建文本路径
            /// </summary>
            /// <param name="word">文本字符串</param>
            /// <param name="point">显示位置</param>
            /// <param name="typeface">字体信息</param>
            /// <param name="fontSize">字体大小</param>
            /// <returns></returns>
            public static Geometry CreateTextPath(string word, Point point, Typeface typeface, int fontSize)
            {
                FormattedText text = new FormattedText(word,
                new System.Globalization.CultureInfo("zh-cn"),
                FlowDirection.LeftToRight, typeface, fontSize,
                Brushes.Black);
                Geometry geo = text.BuildGeometry(point);
                PathGeometry path = geo.GetFlattenedPathGeometry();
                return path;
            }
            #endregion

            #endregion
        }

      
    }
}
